<?php


namespace App\Admin\Controllers\Attribute;

use App\Models\Classify;
use App\Models\Goods;
use App\Models\GoodsClassify;
use App\Models\GoodsSku;
use App\Models\GoodsSkuToMaterial;
use App\Models\Key;
use App\Models\Material;
use App\Models\MaterialClassify;
use App\Models\Purchase;
use App\Models\PurchaseToMaterial;
use App\Models\Sharp;
use App\Models\StoreDetail;
use App\Models\Value;
use Encore\Admin\Facades\Admin;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator;

/**
 * 商品规格控制器
 * Created By FreeAbrams
 * Date: 2020/12/2
 */
class GoodsAttributeController
{
	public function lists(Request $request)
	{
		$condition = [];
		if (isset($request->status)) {
			$condition[] = ['status', '=', $request->status];
		}
		if (isset($request->title)) {
			$condition[] = ['title', 'like', '%' . $request->title . '%'];
		}
		if (isset($request->admin_user_id)) {
			$condition[] = ['admin_user_id', '=', $request->admin_user_id];
		}
		$page = $request->page ? $request->page : 1;
		$limit = $request->limit ? $request->limit : 10;
		$count = Goods::where($condition)->count();
		$page = $limit * ($page - 1);
		$data = Goods::where($condition)->orderBy('created_at', 'DESC')->orderBy('id', 'DESC')->offset($page)->limit($limit)->get()->toArray();
		return response([
			'code' => '0',
			'msg' => '',
			'count' => $count,
			'data' => $data]);
	}
	
	public function create(Request $request)
	{
		$title = "添加商品";
		$condition = [];
		$supplier = AdminUsers::where($condition)->get();
		$tables = GoodsTable::where($condition)->get();
		$labels = Labels::where($condition)->get();
		return view('admin.goods.add', compact('title', 'supplier', 'tables', 'labels'));
	}
	
	public function store(Request $request)
	{
		$data = $request->only('admin_user_id', 'title', 'describe', 'price', 'cost', 'rebate', 'groups_money', 'stock', 'sell', 'images_url', 'original_price', 'express', 'remake');
		$data['merchant_id'] = 1;
		$data['status'] = 1;
		$add = Goods::create($data);
		if ($add) {
			$details = [];
			$details['goods_id'] = $add->id;
			if ($request->input('banner')) {
				$details['banner'] = implode(',', $request->input('banner'));
			}
			if ($request->input('details')) {
				$details['details'] = $request->input('details');
			}
			//GoodsDetails::create($details);
			if ($request->input('tables')) {
				$add->tables()->attach($request->input('tables'));
			}
			if ($request->input('labels')) {
				$add->labels()->attach($request->input('labels'));
			}
			return response([
				'code' => '0',
				'msg' => '',
				'data' => $add]);
		}
		return response([
			'code' => '1005',
			'msg' => '',
			'data' => []]);
	}
	
	public function delete(Request $request)
	{
		$data = $request->only('id');
		$delete = Goods::whereIn('id', explode(',', $data['id']))->delete();
		if ($delete) {
			return response([
				'code' => '0',
				'msg' => '',
				'data' => $delete]);
		}
		return response([
			'code' => '1005',
			'msg' => '',
			'data' => []]);
	}
	
	public function edit($id)
	{
		$data = Goods::with(['tables', 'labels', 'GoodsDetails'])->find($id);
		
		$title = "修改商品";
		$condition = [];
		$supplier = AdminUsers::where($condition)->get();
		$tables = GoodsTable::where($condition)->get();
		$labels = Labels::where($condition)->get();
		return view('admin.goods.edit', compact('title', 'data', 'supplier', 'tables', 'labels'));
	}
	
	public function update(Request $request)
	{
		$data = $request->only('admin_user_id', 'title', 'describe', 'price', 'cost', 'rebate', 'groups_money', 'stock', 'sell', 'images_url', 'original_price', 'id', 'status', 'express', 'remake');
		$goods = Goods::find($data['id']);
		// 判断是否参与秒杀活动
		$res = Sharp::checkThisGoodsIsInSharp(Admin::user()->store_id, $data['id']);
		if ($res) {
			return response()->json(['status' => false, 'message' => '该商品正在参加秒杀活动，暂不方便修改']);
			// 判断结束
		}
		
		if ($goods) {
			$goods->update($data);
			$details = [];
			if ($request->input('banner')) {
				$details['banner'] = implode(',', $request->input('banner'));
			}
			if ($request->input('details')) {
				$details['details'] = $request->input('details');
			}
			//GoodsDetails::where('goods_id', $goods->id)->update($details);
			if ($request->input('tables')) {
				$goods->tables()->sync($request->input('tables'));
			}
			if ($request->input('labels')) {
				$goods->labels()->sync($request->input('labels'));
			}
			if ($request->input('classify')) {
				$goods->getClassify()->sync($request->input('classify'));
			}
			
			if ($request->input('sku')) {
				// 首次设置sku，删除商品与材料联系返回预减库存
				GoodsSku::cutGoodsToMaterial($data['id']);
				$res = GoodsSku::where('goods_id', $data['id'])->get();
				if (array_keys($res->groupBy('id')->toArray())) {
					GoodsSku::whereIn('goods_id', array_keys($res->groupBy('id')->toArray()))->forceDelete();
				}
				GoodsSkuToMaterial::where('goods_sku_id', $data['id'])->forceDelete();
				foreach ($request->input('sku') as $key => $val) {
					$add = [];
					$add['goods_id'] = $data['id'];
					$add['ids'] = json_encode($val['ids']);
					$add['attribute_string'] = $this->attrname($val['ids']);
					$add['stock'] = (int)$val['stock'];
					$add['price'] = (int)($val['price'] * 100);
					$add['cost'] = 0;
					$add['original_price'] = 0;
					$Sku = GoodsSku::create($add);
					// 生成商品
				}
			}
			// 更新
			if ($request->input('sku_update')) {
				// 设置sku，删除商品与材料联系返回预减库存
				GoodsSku::cutGoodsToMaterial($data['id']);
				// 返回库存
				$old_sku = GoodsSku::with(['material'])->where('goods_id', $data['id'])->get();
				GoodsSku::returnStock($old_sku);
				foreach ($request->input('sku_update') as $k => $v) {
					static $sku_id = [];
					static $result = [];
					$add = [];
					$add['goods_id'] = $data['id'];
					$add['ids'] = json_encode($v['ids']);
					$add['attribute_string'] = $this->attrname($v['ids']);
					$add['stock'] = (int)$v['stock'];
					$add['price'] = (int)($v['price'] * 100);
					$add['cost'] = 0;
					$add['original_price'] = 0;
					$sku[$k] = GoodsSku::updateOrCreate([
						'goods_id' => $add['goods_id'],
						'ids' => $add['ids']
					], $add);
					
					$result[$add['attribute_string']] = GoodsSku::checkIniPrice($skuTemp = GoodsSku::with(['material'])->where('id', $sku[$k]['id'])->get());
					
					if (count($skuTemp[0]->material) > 0) {
						static $needs = [];
						$skuTemp[0]->material->map(function ($item) use (&$needs, $add) {
							$needs[$item->material_id] = $item->number * $add['stock'];
						});
						$stock = PurchaseToMaterial::getMaterialsStock(array_keys($needs));
						
						$res = GoodsSku::checkStock($stock, $needs);
						
						if ($res !== true) {
							GoodsSku::where('goods_id', $data['id'])->update(['stock' => 0]);
							return \response([
								'code' => 0,
								'msg' => $res
							]);
						}
					}
				}
				// 材料生成sku库存
				GoodsSku::createStock(collect($sku));
				
				if (checkIniPriceRes($result) !== true) {
					return response([
						'code' => 0,
						'msg' => checkIniPriceRes($result)
					]);
				}
			}
			
			return response([
				'code' => '0',
				'msg' => '添加成功',
				'data' => $goods]);
		}
		return response([
			'code' => '1005',
			'msg' => '',
			'data' => []]);
	}
	
	protected function attrname($array)
	{
		$name = [];
		foreach ($array as $key => $value) {
			foreach ($value as $k => $v) {
				$k_name = Key::where('id', $k)->value('title');
				$v_name = Value::where('id', $v)->value('title');
				$name[] = $k_name . ":" . $v_name;
			}
		}
		return implode(',', $name);
	}
	
	public function tables()
	{
		$title = "商品分类";
		return view('admin.goods.index', compact('title'));
	}
	
	/**
	 * @接口
	 * @Method goods_table.lists
	 * @Name 领券中心
	 * @CreateTime 2019-12-09 16:47:28
	 * @Sign 小肥柴
	 * @return void
	 *
	 **/
	public function table_lists(Request $request)
	{
		$condition = [];
		if (isset($request->title)) {
			$condition[] = ['title', 'like', '%' . $request->title . '%'];
		}
		$page = $request->page ? $request->page : 1;
		$limit = $request->limit ? $request->limit : 10;
		$count = GoodsTable::where($condition)->count();
		$page = $limit * ($page - 1);
		$data = GoodsTable::where($condition)->orderBy('created_at', 'DESC')->orderBy('id', 'DESC')->offset($page)->limit($limit)->get()->toArray();
		return response([
			'code' => '0',
			'msg' => '',
			'count' => $count,
			'data' => $data]);
	}
	
	public function attribute($id)
	{
		$data = Goods::with(['getClassify'])->find($id);
		//dd($data);
		if (isset($data->getClassify[0]) && !empty($data->getClassify[0])) {
			
			$data->classid = $data->getClassify[0]->id;
			$default = [];
			$default = GoodsSku::select('id', 'ids', 'stock', 'price', 'cost', 'original_price')->where('goods_id', $id)->get()->toArray();
		} else {
			$data->classid = 0;
			$default = [];
		}
		$title = "规格属性";
		$condition = ['store_id' => Admin::user()->store_id];
		$classify = Classify::where($condition)->with(['keys'])->get()->toArray();
		$keys = [];
		foreach ($classify as $key => $value) {
			$keys[$value['id']] = [];
			foreach ($value['keys'] as $k => $v) {
				$keys[$value['id']][$k]['id'] = $v['id'];
				$keys[$value['id']][$k]['name'] = $v['title'];
				$keys[$value['id']][$k]['sub'] = [];
				foreach ($v['values'] as $ki => $vi) {
					$keys[$value['id']][$k]['sub'][$ki]['id'] = $vi['id'];
					$keys[$value['id']][$k]['sub'][$ki]['name'] = $vi['title'];
				}
			}
		}
		return view('admin.goods.attribute', compact('title', 'data', 'classify', 'keys', 'default'));
	}
	
	public function value_add(Request $request)
	{
		// 参数验证
		$validate = Validator::make($request->all(), [
			'keys' => 'required',
			'title' => 'required'
		]);
		if ($validate->fails()) {
			return response([
				'code' => 1,
				'msg' => $validate->errors()->first(),
				'data' => ''
			]);
		}
		$data = $request->only('title');
		$data['sort'] = 255;
		$data['store_id'] = Admin::user()->store_id;
		$add = Value::create($data);
		if ($add) {
			$add->keys()->attach($request->input('keys'));
			return response([
				'code' => '0',
				'msg' => '',
				'data' => $add]);
		}
	}
	
	// 材料渲染
	public function material($id)
	{
		$materialClassify = MaterialClassify::selectOptions();
		$materialClassify = Arr::except($materialClassify, '0');
		ksort($materialClassify);
		$materials = Material::pluck('name', 'id');
		// 返回默认数据
		$data = [];
		$default = GoodsSku::where('id', $id)->with(['materials'])->get(['id']);
		foreach ($default as $v) {
			$data = $v->materials;
		}
		$default = $data;
		return view('admin.goods.material', compact('materialClassify', 'materials', 'default', 'id'));
	}
	
	// 选择分类按钮后更新当前列材料数据
	public function getMaterials(Request $request)
	{
		// 获取已经选择的材料id
		$materials_id = $request->post('material_id');
		$ids = [];
		foreach ($materials_id as $k => $v) {
			if (!empty($v) && $v !== '请选择') {
				$ids[] = $v;
			}
		}
		
		$materials = Material::where('material_classify_id', $request->post('id'))
			->whereNotIn('id', $ids)
			->get(['id', 'material_classify_id', 'name']);
		
		return response([
			'code' => 1,
			'msg' => '查询成功',
			'data' => $materials
		]);
	}
	
	// 保存材料设置
	// I: 判断当前sku单价 * (1+ 总部抽成sharing_percent%) 是否 >= 设置材料数量*批次价格
	// II: 减少材料库存
	// III: 验证成功后生成材料消耗（生成商品）记录X条
	public function updateMaterials(Request $request)
	{
		// 表单验证
		$validate = Validator::make($request->all(), [
			'materials' => 'required',
			'numbers' => 'required'
		]);
		if ($validate->fails()) {
			return false;
		}
		
		// 组装sku材料多对多关系数据
		$materials = $request->post('materials');
		$number = $request->post('numbers');
		
		$data = [];
		$material_ids = [];
		$tempNeeds = [];
		$msg = '更新成功';
		$goodsSku = GoodsSku::with(['material'])->find($request->post('id'));
		
		// 如果修改了材料当前sku库存归零 返回材料 之后控制器里的代码不执行
		
		foreach ($materials as $k => $v) {
			$material_ids[] = $v['material_id'];
			$data[$v['material_id']] = ['number' => $number[$k]['number']];
			$tempNeeds[$v['material_id']] = $number[$k]['number'];
		}
		$res = GoodsSku::checkMaterial($goodsSku, $tempNeeds);
		if ($res) {
			if (!empty($goodsSku->material->pivot)) {
				GoodsSku::returnStock(collect([$goodsSku]));
				$goodsSku->stock = 0;
				$goodsSku->save();
			}
			$goodsSku->stock = 0;
			$goodsSku->save();
			// 重新绑定材料
			$goodsSku->materials()->withTimestamps()->sync($data);
			return response([
				'code' => 1,
				'msg' => '修改成功, 剩余材料已返回库存'
			]);
		}
		
		// 应当减少的库存 = sku 设置库存 * 设置材料数量
		$stock = PurchaseToMaterial::getMaterialsStock($material_ids);
		$initPrice = PurchaseToMaterial::getMaterialsPrice($material_ids);
		$unit_price = $initPrice->groupBy('material_id')->toArray();
		
		$needs = [];
		$material_needs = [];
		foreach ($data as $k => $v) {
			$needs[$k] = $goodsSku->stock * $v['number'];
			$material_needs[$k] = $v['number'];
		}
		
		// 检测sku价格是否设置正确
		$detail = StoreDetail::find(Admin::user()->store_id);
		$limitSkuPrice = GoodsSkuToMaterial::limitPrice($unit_price, $material_needs, $detail->sharing_percent, $goodsSku);
		
		if ($limitSkuPrice !== true) {
			$msg = $limitSkuPrice;
		}
		
		// 检测材料库存是否充足
		$mini = GoodsSkuToMaterial::mini_stock($stock->toArray(), $needs);
		if (!$mini) {
			return response([
				'code' => 1,
				'msg' => '存在库存不足的材料，暂时无法设置'
			]);
		}
		
		// 减少库存
		//$stocks = PurchaseToMaterial::getPurchases($material_ids);
		//GoodsSkuToMaterial::reduce($stocks, $needs);
		
		// 保存sku材料多对多关系
		
		$res = $goodsSku->materials()->withTimestamps()->sync($data);
		
		if ($res) {
			return response([
				'code' => 1,
				'msg' => $msg
			]);
		}
		
		return response([
			'code' => 1,
			'msg' => '更新失败'
		]);
	}
}